package com.tsfyun.scm.service.impl.customs;

import com.tsfyun.common.base.dto.DeclareBizReceiveDTO;
import com.tsfyun.common.base.dto.TaskDTO;
import com.tsfyun.common.base.enums.ManifestStatusEnum;
import com.tsfyun.common.base.enums.domain.DeclarationStatusEnum;
import com.tsfyun.common.base.enums.domain.DomainOprationEnum;
import com.tsfyun.common.base.enums.domain.DomainTypeEnum;
import com.tsfyun.common.base.enums.singlewindow.SingleWindowDeclarationStatusEnum;
import com.tsfyun.common.base.enums.singlewindow.SingleWindowLogEnum;
import com.tsfyun.common.base.util.StringUtils;
import com.tsfyun.scm.entity.customs.Declaration;
import com.tsfyun.scm.entity.customs.LogSingleWindow;
import com.tsfyun.scm.service.customs.IDeclarationReceiptService;
import com.tsfyun.scm.service.customs.IDeclarationService;
import com.tsfyun.scm.service.customs.ILogSingleWindowService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class DeclarationReceiptServiceImpl implements IDeclarationReceiptService {

    @Autowired
    private IDeclarationService declarationService;
    @Autowired
    private ILogSingleWindowService logSingleWindowService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void receive(DeclareBizReceiveDTO dto) {
        SingleWindowLogEnum singleWindowLogEnum = SingleWindowLogEnum.of(dto.getType());
        //写入单一窗口日志
        LogSingleWindow logSingleWindow = new LogSingleWindow();
        logSingleWindow.setDomainId(dto.getBillNo());//单据编号
        logSingleWindow.setDomainType(singleWindowLogEnum.getCode());
        logSingleWindow.setNode(dto.getNode());
        logSingleWindow.setCreateBy("系统");
        logSingleWindow.setDateCreated(LocalDateTime.now());
        logSingleWindow.setMemo(dto.getMemo());
        if(StringUtils.isNotEmpty(logSingleWindow.getMemo())&&logSingleWindow.getMemo().length()>500){
            logSingleWindow.setMemo(dto.getMemo().substring(0,499));
        }
        logSingleWindowService.saveNonNull(logSingleWindow);
        switch (singleWindowLogEnum){
            case DECLARE://报关单
                handleDeclare(dto);
                break;
            case MANIFEST://舱单
                handleMaifest(dto);
                break;
        }
    }
    private static final List<String> clearances = Arrays.asList("P","K","W","I","X");
    @Transactional(rollbackFor = Exception.class)
    public void handleDeclare(DeclareBizReceiveDTO dto){
        Declaration declaration = declarationService.findByDocNo(dto.getBillNo());
        if(Objects.isNull(declaration)){return;}
        declaration.setDeclarationStatus("0".equals(dto.getStatus())?SingleWindowDeclarationStatusEnum.IMPORT_SUCCESS.getCode():SingleWindowDeclarationStatusEnum.IMPORT_FAIL.getCode());
        //统一编号
        if(StringUtils.isNotEmpty(dto.getCusCiqNo())){
            declaration.setCusCiqNo(dto.getCusCiqNo());
        }
        //报关单号
        if(StringUtils.isNotEmpty(dto.getEntryId())){
            declaration.setDeclarationNo(dto.getEntryId());
        }
        //修改报关单
        declarationService.updateById(declaration);
        //P/K/W/I/X-放行
        if(clearances.contains(dto.getChannel()) && Objects.equals(DeclarationStatusEnum.IN_DECLARE,DeclarationStatusEnum.of(declaration.getStatusId()))){
            TaskDTO taskDTO = new TaskDTO();
            taskDTO.setDocumentId(declaration.getId());
            taskDTO.setDocumentClass(DomainTypeEnum.DECLARATION.getCode());
            taskDTO.setOperation(DomainOprationEnum.DECLARATION_COMPLETED.getCode());
            taskDTO.setNewStatusCode(DeclarationStatusEnum.COMPLETE.getCode());
            taskDTO.setMemo("报关单已放行系统自动通过");
            taskDTO.setOperator("系统");
            declarationService.declarationCompleted(taskDTO);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void handleMaifest(DeclareBizReceiveDTO dto){
        Declaration declaration = declarationService.findManifestById(Long.valueOf(dto.getBillNo()));
        if(Objects.isNull(declaration)){
            log.error(String.format("舱单【%s】未找到报关舱单数据"),dto.getBillNo());
            return;
        }
        declaration.setManifestSwStatus("0".equals(dto.getStatus())?SingleWindowDeclarationStatusEnum.IMPORT_SUCCESS.getCode():SingleWindowDeclarationStatusEnum.IMPORT_FAIL.getCode());
        ManifestStatusEnum statusEnum = null;
        switch (dto.getChannel()){
            case "E3"://发往海关成功
                statusEnum = ManifestStatusEnum.SAVED;
                break;
            case "0"://调用成功
                statusEnum = ManifestStatusEnum.SAVED;
                break;
            case "01"://接受申报
                if("9".equals(dto.getFunctionCode())){
                    statusEnum = ManifestStatusEnum.DECLARED;
                }else if("3".equals(dto.getFunctionCode())){
                    statusEnum = ManifestStatusEnum.REMOVE;
                }
                break;
            case "02"://转人工审核
                statusEnum = ManifestStatusEnum.UNDERREVIEW;
                break;
            case "03"://报文填制不规范
                statusEnum = ManifestStatusEnum.CHARGEBACK;
                break;
            default:
                statusEnum = ManifestStatusEnum.FAILED;
                break;
        }
        //更新舱单状态
        declarationService.updateManifestReceiptData(declaration.getManifestId(),statusEnum.getCode(),declaration.getManifestSwStatus());
    }
}
